/* eslint-disable no-unused-vars */
/* eslint-disable arrow-body-style */
import Axios from 'axios';

import axiosConfig from './config';

function getRequestTag(config) {
  const { url, method, params } = config;
  return `${url}&${method}&${JSON.stringify(params)}`;
}

// 声明一个数组用于存储每个ajax请求的取消函数和ajax标识
const cancelTokens = [];
function cancelRequest(config) {
  cancelTokens.forEach((cancelToken, i) => {
    const { tag, cancel } = cancelToken;
    // 当当前请求在数组中存在时执行函数体
    if (tag === getRequestTag(config)) {
      // 执行取消操作
      cancel();

      // 把这条记录从数组中移除
      cancelTokens.splice(i, 1);
    }
  });
}

export default function createAxios(options) {
  const axios = Axios.create({
    ...axiosConfig,
    ...options,
  });

  let counter = 0;
  // 添加请求拦截器，在发送请求之前做些什么
  axios.interceptors.request.use(
    config => {
      console.log('请求拦截器', config);
      counter += 1;
      //
      const { method, params } = config;
      let newConfig = config;
      if (method && method.toUpperCase() === 'POST') {
        newConfig = {
          ...config,
          params: { data: params },
        };
      }
      // 在一个ajax发送前执行一下取消操作
      cancelRequest(config);
      //
      newConfig = {
        ...config,
        cancelToken: new Axios.CancelToken(cancel => {
          // 这里的ajax标识用请求地址&请求方式拼接的字符串
          cancelTokens.push({ tag: getRequestTag(config), cancel });
        }),
      };
      return newConfig;
    },
    error => {
      // 对请求错误做些什么
      return Promise.reject(error);
    },
  );

  // 添加响应拦截器，对响应数据做点什么
  axios.interceptors.response.use(
    response => {
      console.log('响应拦截器', response);
      counter -= 1;
      if (counter === 0) {
        // store.dispatch(toggleLoading); // 隐藏菊花
      }
      // 在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
      cancelRequest(response.config);

      return response;
    },
    error => {
      // console.log('error', error);
      // 对响应错误做点什么1
      // return Promise.reject(error);
      counter -= 1;
      if (counter === 0) {
        // store.dispatch(toggleLoading); // 隐藏菊花
      }
      return { data: {}, error: true };
    },
  );
  return axios;
}
